/**
 * @file i2cOpt.c
 * @brief   
 * @author  xiaowine (xiaowine@sina.cn)
 * @version 01.00
 * @date    2021-04-09
 * 
 * @copyright Copyright (c) {2020}  xiaowine
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2021-04-09 <td>1.0     <td>wangh     <td>内容
 * </table>
 * ******************************************************************
 * *                   .::::
 * *                 .::::::::
 * *                ::::::::::
 * *             ..:::::::::::
 * *          '::::::::::::
 * *            .:::::::::
 * *       '::::::::::::::..        女神助攻,流量冲天
 * *            ..::::::::::::.     永不宕机,代码无bug
 * *          ``:::::::::::::::
 * *           ::::``:::::::::'        .:::
 * *          ::::'   ':::::'       .::::::::
 * *        .::::'      ::::     .:::::::'::::
 * *       .:::'       :::::  .:::::::::' ':::::
 * *      .::'        :::::.:::::::::'      ':::::
 * *     .::'         ::::::::::::::'         ``::::
 * * ...:::           ::::::::::::'              ``::
 * *```` ':.          ':::::::::'                  ::::.
 * *                   '.:::::'                    ':'````.
 * ******************************************************************
 */

/* Private includes ----------------------------------------------------------*/
#include "i2cOpt.h"
#include "stm32f0xx_hal.h"
#include <string.h>
#include "user_data.h"
/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
#define I2CDMASIZE 20

#define BUFFERSIZE_RX 30
#define BUFFERSIZE_TX 30
/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
volatile uint8_t i2cDmaRxBuffer[BUFFERSIZE_RX] = {0};
volatile uint8_t i2cDmaTxBuffer[BUFFERSIZE_TX] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
volatile uint8_t I2cDataIn[30] = {0};
volatile uint8_t I2cDataOut[30] = {0};
/* Public variables ----------------------------------------------------------*/
extern I2C_HandleTypeDef hi2c1;
extern osThreadId I2cTid;
/* Private function prototypes -----------------------------------------------*/

/* Private user code ---------------------------------------------------------*/

void i2cProc(void const *argument)
{
    osEvent i2cTxEvent;
    if (HAL_I2C_Slave_Receive_DMA(&hi2c1, (uint8_t *)i2cDmaRxBuffer, I2CDMASIZE) != HAL_OK)
    {
        //Error_Handler();
        //osDelay(10);
    }
    while (1)
    {
        i2cTxEvent = osSignalWait(1, 1200);
        if (i2cTxEvent.status == osEventTimeout)
        {
            if (READ_REG(hi2c1.Instance->ISR) & I2C_FLAG_BUSY)
            {
                HAL_I2C_DeInit(&hi2c1); //释放IO口为GPIO，复位句柄状态标志
                HAL_I2C_Init(&hi2c1);   //这句重新初始化I2C控制器
            }
            if (HAL_I2C_GetState(&hi2c1) == HAL_I2C_STATE_READY)
            {
                if (HAL_I2C_Slave_Receive_DMA(&hi2c1, (uint8_t *)i2cDmaRxBuffer, I2CDMASIZE) != HAL_OK)
                {
                    //Error_Handler();
                }
            }
        }
    }
}

void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
    osSignalSet(I2cTid, 1);
    if (HAL_I2C_GetState(&hi2c1) == HAL_I2C_STATE_READY)
    {
        if (HAL_I2C_Slave_Receive_DMA(&hi2c1, (uint8_t *)i2cDmaRxBuffer, I2CDMASIZE) != HAL_OK)
        {
            //Error_Handler();
        }
    }
    I2COutOkFlag = 1;
}

void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
    memcpy((void *)i2cDmaTxBuffer, (void *)I2cDataOut, 20);
    if (HAL_I2C_GetState(&hi2c1) == HAL_I2C_STATE_READY)
    {
        if (HAL_I2C_Slave_Transmit_DMA(&hi2c1, (uint8_t *)i2cDmaTxBuffer, I2CDMASIZE) != HAL_OK)
        {
            //Error_Handler();
        }
    }
    memcpy((void *)I2cDataIn, (void *)i2cDmaRxBuffer, 20);
    I2CInOkFlag = 1;
}

void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
{
    /* Get current IT Flags and IT sources value */

    if ((HAL_I2C_GetState(&hi2c1) == HAL_I2C_STATE_READY) && (hi2c->ErrorCode == HAL_I2C_ERROR_AF))
        HAL_I2C_SlaveRxCpltCallback(hi2c);
    else
    {
        if (HAL_I2C_GetState(&hi2c1) == HAL_I2C_STATE_READY)
        {
            if (HAL_I2C_Slave_Receive_DMA(&hi2c1, (uint8_t *)i2cDmaRxBuffer, I2CDMASIZE) != HAL_OK)
            {
                //Error_Handler();
            }
        }
    }
}
